Skip to content

Qml staging - #4

Open
johnny9 wants to merge 1239 commits into
qt6-devfrom
qml-staging
Open

Qml staging#4
johnny9 wants to merge 1239 commits into
qt6-devfrom
qml-staging

Conversation

@johnny9

@johnny9 johnny9 commented Jun 14, 2026

Copy link
Copy Markdown
Owner

No description provided.

johnny9 and others added 30 commits May 2, 2026 23:38
The "../controls" import is needed to resolve Theme, which is
used throughout the component for colors. Without it, QML raises
"ReferenceError: Theme is not defined" at runtime.

Rebased-From: bfc2389
Github-Pull: bitcoin-core#532
bfc2389 qml: Add missing controls import to MonospaceOutputView (epicleafies)
2551988 qml: Remove legacy Developer Options debug log entry (epicleafies)
e986dfb qml: Remove legacy debug log reader from NodeModel (epicleafies)
4f863a5 qml: Add debug log viewer page (epicleafies)
6a85a83 qml: Add MonospaceOutputView shared component (epicleafies)
4019e7e qml: fix "Load more" showing when all log entries are already loaded (epicleafies)
057cc8b test: fixed object not found error (epicleafies)
91c1c3f test: added debug log tests to github workflows (epicleafies)
aef31ea test: fix duplicate wait_for_property shadowing predicate overload (epicleafies)
8091f39 qml: add in-app debug log viewer (epicleafies)
bb533e7 qml: add debug log reader to NodeModel (epicleafies)

Pull request description:

  Created the debug log page bitcoin-core#510.
  Created functional and C++ unit tests for the debug log page.
  The debug log is viewable within the page and can be viewed in an external text editor.
  Debug log can be updated by the user and also auto updates.
  Debug log automatically loads some of the logs and user can load more.
  <img width="660" height="897" alt="Screenshot from 2026-03-11 21-35-00" src="https://github.com/user-attachments/assets/c5f13511-e7ce-4fc4-ac15-e1ba49f87e16" />
  <img width="660" height="897" alt="Screenshot from 2026-03-11 21-35-22" src="https://github.com/user-attachments/assets/eb1e8555-a327-4fc4-ba93-d8c56b70caa8" />

ACKs for top commit:
  johnny9:
    ACK [bfc2389](bitcoin-core@bfc2389)

Rebased-From: 852bd07
Github-Pull: bitcoin-core#532
658882b qml: Introduce navigation policy to opt out of back button and apply to wallet creation (pseudoramdom)

Pull request description:

  Fixes bitcoin-core#572

  This change adds a small shared navigation policy to `PageStack` and ties `NavigationBar2` into it. `PageStack` now exposes `canGoBack` and `goBack()`,
  - pages can opt out by setting `navigationBackEnabled: false`
  - `NavigationBar2` can now take a navigationStack and render a default Back button based on that stack’s `canGoBack`, calling `goBack()` when clicked.

  The wallet creation flow now uses this shared behavior instead of hand-rolling Back buttons and back signal.

ACKs for top commit:
  johnny9:
    ACK 658882b

Rebased-From: 56163a3
Github-Pull: bitcoin-core#687
f3ca7a0 qml: improve send fee feedback (johnny9)
e5fab68 test: add wallet model unit tests for include-fee flow (johnny9)
6f82cd1 test: add qml coverage for include-fee send flow (johnny9)
9a1147e qml: add include-fee-in-amount send toggle (johnny9)
76270f2 qml: remove font.features, requires qt6.6+ (johnny9)
8c5b263 qml: add custom fee rate mode (johnny9)
e747bd0 test: exercise fee preset dropdown (johnny9)
300ff56 test: check send fee preview parity (johnny9)
64f413d test: avoid double-linking qml unit sources (johnny9)
40cc7ad wallet: use static regtest fees for previews (johnny9)
d6de483 qml: simplify fee selection popup sizing (johnny9)
105782b qml: stabilize fee selection popup layout (johnny9)
ea6797c wallet: add fallback fee preview estimates (johnny9)
f227357 qml: add standard fee selection estimates (johnny9)

Pull request description:

  <img width="639" height="693" alt="image" src="https://github.com/user-attachments/assets/4c9653a5-574a-4147-8dc9-e76b77aadb7f" />
  <img width="639" height="693" alt="image" src="https://github.com/user-attachments/assets/29cfe88c-8cd9-437d-89ff-d1cc00ecd488" />
  <img width="639" height="693" alt="image" src="https://github.com/user-attachments/assets/3c310061-f444-47cd-8ff2-e2e8f2d9b976" />

  Wires up fee selection in the Send page. Overrides are in place for Regtest where CoinControl fee estimations aren't supported.

ACKs for top commit:
  MarnixCroes:
    ACK f3ca7a0

Rebased-From: 98954ad
Github-Pull: bitcoin-core#546
…the wallet

3268d3e qml: Dim conflicted transactions in activity list (pseudoramdom)
2cf482b test: Add functional tests for RBF flow (pseudoramdom)
5999e80 test: Add bump transaction model unit tests & qml tests (pseudoramdom)
f4ff2b8 qml: Implement Replace-by-fee (pseudoramdom)

Pull request description:

  Bring support to "Speed up" unconfirmed transactions by bumping fees (bitcoin-core#521)

  - Add `BumpTransactionModel` to manage the fee bump flow
  - Add `SpeedUpOverlay` popup to review and confirm the higher-fee replacement transaction
  - Add a reusable` InfoBanner` component for contextual actions/status
    -  Show a speed up banner in transaction details for bumpable transactions
    - Show a replacement-status banner in transaction details when a transaction has been replaced

  #### Review note
  - ~~This PR is stacked on top of bitcoin-core#546 (a4de80b)~~ Now merged and this PR is rebased

  ### Screenshots

  <img width="1181" height="906" alt="Screenshot 2026-04-24 at 2 51 49 PM" src="https://github.com/user-attachments/assets/93f3a27d-a540-4adb-95ff-0ff339ae3e0d" />
  <img width="1428" height="1127" alt="Screenshot 2026-04-25 at 1 18 36 PM" src="https://github.com/user-attachments/assets/d91dd115-4f94-473a-8019-21073555bab3" />
  <img width="1428" height="1127" alt="Screenshot 2026-04-25 at 1 19 16 PM" src="https://github.com/user-attachments/assets/73e40893-4f9c-493c-bf6e-6eefe3692f6a" />
  <img width="1428" height="1127" alt="Screenshot 2026-04-25 at 1 19 32 PM" src="https://github.com/user-attachments/assets/189a4163-5565-452a-ba5d-ae9c17a71868" />

ACKs for top commit:
  johnny9:
    ACK 3268d3e

Rebased-From: f36b151
Github-Pull: bitcoin-core#554
johnny9 and others added 30 commits June 3, 2026 11:45
Verify the subtract-fee receiver output matches the preview-adjusted amount, keep review-only send flows free of wallet and mempool side effects, and assert the RBF passphrase flow leaves the wallet locked.

Rebased-From: c0f553e
Github-Pull: bitcoin-core#736
Connect QClipboard::dataChanged to a new QML-accessible signal on the
Clipboard singleton. The Send page uses this to detect when a bitcoin:
URI is copied so it can show the clipboard import banner automatically.

Rebased-From: c3879ce
Github-Pull: bitcoin-core#736
Implement a standalone BIP21 bitcoin: URI parser in
qml/models/bitcoinuri.{h,cpp}. The parser validates the address
via DecodeDestination, handles the standard amount/label/message
query parameters with full percent-decoding (QUrl::FullyDecoded),
rejects bitcoin:// double-slash URIs, and honours the req- prefix
semantics by failing on unknown required parameters.

Add 17 unit tests covering valid URIs, all rejection cases, edge
cases (zero amount, empty amount param, duplicate amount, uppercase
scheme, legacy P2PKH address) and req- behaviour.

Rebased-From: 242dd67
Github-Pull: bitcoin-core#736
Add two Q_INVOKABLE methods:
- parseBitcoinUri(uri_text): parse a bitcoin: URI from a string
- parseBitcoinUriFromFile(source_path): read a local file and parse
  its contents as a URI; accepts both plain paths and file:// URLs
  (using QUrl::toLocalFile for cross-platform correctness)

Both return a QVariantMap with success/error/address/amountSats/
hasAmount/label/hasLabel/uriMessage/hasMessage keys. The key is named
"uriMessage" rather than "message" to avoid shadowing JavaScript's
built-in Error.message property in QML error-handling code.

File reads are capped at 1 MiB and performed synchronously on the
GUI thread, which is acceptable for local storage.

Rebased-From: 72ab6a8
Github-Pull: bitcoin-core#736
Capitalise "Bitcoin" when used as a proper noun in prose, drop the
colon (which belongs to the URI scheme syntax, not sentences), and
replace the redundant "URI cannot be parsed." prefix with concise
standalone messages that read naturally on their own:

  "Enter a Bitcoin payment URI."
  "Not a valid Bitcoin payment URI."
  "Invalid Bitcoin amount."
  "Unsupported required parameter: <key>"

Update unit test assertions to match.

Rebased-From: fcf2cfa
Github-Pull: bitcoin-core#736
parseBitcoinUri and parseBitcoinUriFromFile have no dependency on wallet
state — they only need chain params, which are globally available after
baseInitialize(). Placing them on WalletQmlModel forces callers to guard
against a null wallet for an operation that does not require one.

Move both methods and BuildBitcoinUriResultMap into a new BitcoinUriModel
class (qml/models/bitcoinurimodel.{h,cpp}) and register it as the "BitcoinUri"
singleton in org.bitcoincore.qt 1.0, alongside Clipboard. QML callers now
use BitcoinUri.parseBitcoinUri() / BitcoinUri.parseBitcoinUriFromFile()
instead of wallet.parseBitcoinUri().

Also replace the C-style (qlonglong) cast in BuildBitcoinUriResultMap with
static_cast<qlonglong> for consistency with the rest of the codebase.

Rebased-From: eddc283
Github-Pull: bitcoin-core#736
The previous code had two problems: the decode_error string from
DecodeDestination is an untranslated C++ internal message that bypasses
the tr() system and appears raw in the UI, and the decode_error.empty()
fallback ("URI cannot be parsed. Use a valid bitcoin: payment URI.") was
inconsistent with the concise phrasing used for all other error messages
in the parser.

Replace both branches with a single translated message: "Not a valid
Bitcoin address."

Rebased-From: a892a79
Github-Pull: bitcoin-core#736
Add an EllipsisMenuButtonItem at the top of the Send options popup
that emits an openPaymentRequest() signal. The Send page listens for
this signal to open the manual URI entry popup. Switch the popup
height to content-driven (columnLayout.implicitHeight + padding)
so it grows automatically with new entries. Anchor the column to
the popup edges rather than centering it.

Rebased-From: 7eea5b7
Github-Pull: bitcoin-core#736
Add four ways to import a BIP21 bitcoin: payment URI into the Send form:

1. Clipboard banner — shown automatically when a valid bitcoin: URI is
   detected in the clipboard (via the Clipboard.dataChanged signal).
   Fill/Dismiss buttons let the user apply or ignore it.

2. Manual popup — the "Open payment request" entry in the Send options
   menu opens a modal dialog where the user can paste or type a URI.

3. File import — via a DropArea that handles text/uri-list drops with
   file:// URLs; the C++ layer converts them to local paths using
   QUrl::toLocalFile().

4. Drag-and-drop — the same DropArea also accepts text/plain drops
   (raw URIs dragged from another app) and non-file URLs.

Successful import populates the address, amount, and note fields and
shows a status row. Failed import shows an error in the same row.
The "message=" field from the URI is displayed separately above the
status row.

Test automation hooks (hidden CoreTextFields + invisible Buttons) are
conditionally loaded inside a Loader gated on the testAutomationEnabled
context property (set in bitcoin.cpp at startup). In production builds
the Loader is inactive and contributes nothing to the object tree.

Rebased-From: a7a3823
Github-Pull: bitcoin-core#736
Track clipboard URI state with three flags: m_pendingClipboardUri
(cached at detection time to avoid TOCTOU races on Fill), m_filledUri
(soft suppress: hides banner while form still matches URI fields,
re-shows when any specified field diverges), and m_dismissedUri (hard
suppress: hides banner until clipboard changes to a different URI).

Add field-change Connections on address, amount and label guarded by
m_applyingUri so programmatic fills do not re-trigger checkClipboard()
before m_filledUri is set by the Fill handler. Move m_applyingUri = false
to after all field writes in applyParsedPaymentRequest for the same reason.

Guard checkClipboard() against !root.visible and null wallet, and run it
from onVisibleChanged so the banner appears when navigating to Send with
a valid URI already in the clipboard. Clear all URI import state on wallet
switch. Update parse call sites to use the BitcoinUri singleton.

Rebased-From: 5ed2f6d
Github-Pull: bitcoin-core#736
The clipboard banner dismiss button and the payment request status clear
button have no visible label. Add Accessible.name and Accessible.role so
screen readers can announce their purpose.

Rebased-From: b58fb8a
Github-Pull: bitcoin-core#736
When a URI is applied via the manual entry popup (or drag-and-drop),
and that URI happens to match what is currently on the clipboard, the
clipboard URI banner should disappear — the same way it does when the
user clicks Fill. Previously the banner would stay visible because only
the Fill button set m_filledUri.

Apply the same soft-suppression logic in applyPaymentRequestFromText:
if the applied URI equals the current clipboard text, set m_filledUri
and hide the banner. The banner will re-appear automatically if the
user later edits any field that the URI populated, preserving the
existing fill-suppression semantics.

Rebased-From: 23d4e8c
Github-Pull: bitcoin-core#736
The paymentRequestStatus and paymentRequestMessage banners are
page-level properties but describe an import that applies to a
specific recipient. When the user navigates to a different
recipient (next/prev/add/remove), the banners remain visible on
the new, empty form — making it appear as though the new
recipient already has an imported payment request.

Clear the banners on currentRecipientChanged so they are only
shown for the recipient they describe. Also clear them when the
address field is emptied, since the import result is no longer
relevant once the address is gone.

Rebased-From: b1a47b1
Github-Pull: bitcoin-core#736
Clicking Apply with an empty input field called
applyPaymentRequestFromText("") which showed a red error banner
alongside any previously imported payment request, creating a
confusing mixed state with valid form fields and a new error.

Prevent this by disabling Apply when the input is empty.

Rebased-From: ac98c48
Github-Pull: bitcoin-core#736
A URI message= value with no whitespace (e.g. a long unbroken
string) caused the banner text to overflow the container since
wrapMode: WordWrap has no break points. Cap display at 3 lines
and elide the remainder with an ellipsis.

Rebased-From: 1e547a0
Github-Pull: bitcoin-core#736
Add qml_test_uri_import.py covering seven URI import scenarios:
1. Clipboard banner: set clipboard to a valid URI, banner appears,
   Fill button populates address/amount/label/message fields.
2. Manual popup: open via the Send options menu, type a URI, apply.
3. Malformed URI error: bitcoin:// is rejected; error shown in status row.
4. File import: write a URI to a temp file, trigger via automation hook.
5. Drag-drop (text): simulate drop of a plain URI string.
6. Drag-drop (file://): simulate drop of a file:// URL via automation hook.
7. Drag-drop (non-file URL): exercises the non-file URL branch of DropArea.

The test drives the full wallet creation wizard before running URI tests
so it can obtain a real regtest address via RPC. The RPC port is
assigned dynamically by QmlTestHarness to prevent port conflicts.

Register the test in the CI workflow.

Rebased-From: e44eb88
Github-Pull: bitcoin-core#736
fdb30e8 qml: refresh fee estimates after URI import (johnny9)
a882898 test: handle wallet type selector in qt compat flow (johnny9)
b664ba4 qml: fix URI import QML integration issues (johnny9)
e44eb88 test: add end-to-end functional test for URI import (epicleafies)
4fb95c7 test: add set_clipboard_text bridge command and extend QmlDriver (epicleafies)
1e547a0 qt: elide long URI message text after 3 lines (epicleafies)
ac98c48 qt: disable URI import popup Apply button when input is empty (epicleafies)
b1a47b1 qt: clear URI import status when recipient or address changes (epicleafies)
23d4e8c qt: hide clipboard URI banner when payment request is applied from it (epicleafies)
b58fb8a qt: add accessibility names to Send page icon-only buttons (epicleafies)
5ed2f6d qt: fix clipboard URI banner state management on Send page (epicleafies)
a7a3823 qt: add URI import to Send page (epicleafies)
7eea5b7 qt: add "Open payment request" to SendOptionsPopup (epicleafies)
a892a79 qt: fix invalid-address error message in BitcoinUri parser (epicleafies)
eddc283 qt: extract URI parsing into BitcoinUriModel singleton (epicleafies)
fcf2cfa qt: fix grammar in BitcoinUri error messages (epicleafies)
72ab6a8 qt: expose bitcoin URI parsing on WalletQmlModel (epicleafies)
242dd67 qt: add BitcoinUri parser model (epicleafies)
c3879ce qt: add Clipboard.dataChanged signal (epicleafies)
79e2232 qml: hide initial RBF unlock error text (johnny9)
579492d qml: invalidate stale send fee previews (johnny9)
c0f553e test: strengthen qml send flow assertions (johnny9)
fb38863 ci: run all qml functional tests (johnny9)
63bd649 qml: respect selected inputs in send balance checks (johnny9)
4897aeb qml: make selected coin inputs exclusive (johnny9)
ec2e7e3 test: cover startup wallet shutdown interrupts (johnny9)
69820a3 qml: use node dust relay fee for send validation (johnny9)
9fe78ca qml: disconnect all node model core signals (johnny9)
88b2963 qml: wire create backup view file action (johnny9)
0f9d67a qml: use fee estimation early to block invalid send (johnny9)
2ede4fe qml: share bitcoin amount input behavior (johnny9)
25b1a43 qml: focus current wallet password field (johnny9)
a906073 qml: fix NavButton content padding (johnny9)
fc6c45c qml: keep receive request history bitcoin-qt compatible (johnny9)
188cbaf qml: unsubscribe NodeModel core signals on destruction (johnny9)
62bbdff qml: shut down cleanly after interrupted init (johnny9)
dadcb29 qml: prompt for wallet password when bumping fees (johnny9)
140af8c qml: clear coin control selection after send (johnny9)
1e2ce1b qml: avoid address generation for fee previews (johnny9)
5e8e64f qml: validate send recipients before review (johnny9)

Pull request description:

  This PR groups Preview-targeted fixes around Send correctness, fee preview behavior, wallet shutdown/lifecycle handling, receive-request compatibility, and small wallet UI polish.

  ## Issues
  Fixes bitcoin-core#467 - Send amount validation accounts for the selected fee estimate before allowing review.
  Fixes bitcoin-core#624 - Create-backup `View file` opens the selected wallet location and reports failures.
  Fixes bitcoin-core#636 - Fee bump confirmation prompts to unlock encrypted wallets and relocks after signing.
  Fixes bitcoin-core#692 - RBF speed-up prompts to unlock encrypted wallets before confirming and is covered by the encrypted-wallet RBF functional test.
  Fixes bitcoin-core#659 - Send validation rejects duplicate recipients and dust outputs before review.
  Fixes bitcoin-core#665 - Coin control selections are cleared after send and when clearing recipients.
  Fixes bitcoin-core#739 - QML coin control treats manually selected coins as exclusive during fee preview and transaction preparation.
  Fixes bitcoin-core#705 - Send review stays disabled when any visible multi-recipient row is incomplete, with a clear validation error.
  Fixes bitcoin-core#712 - Update-password mode focuses the current-password field first.
  Fixes bitcoin-core#715 - Fee previews no longer create persistent `qml-fee-preview` wallet addresses.
  Fixes bitcoin-core#721 - Receive request serialization stays compatible with bitcoin-qt and is covered by a bitcoin-qt v31.0 regression workflow.
  Fixes bitcoin-core#728 - Navigation button content padding is restored.
  Fixes bitcoin-core#730 - `NodeModel` unsubscribes from core signals during destruction.
  Fixes bitcoin-core#731 - SIGINT/Ctrl+C during interrupted initialization exits cleanly instead of hanging.

  Refs bitcoin-core#582
  Refs bitcoin-core#577
  Refs bitcoin-core#579

ACKs for top commit:
  pseudoramdom:
    ACK fdb30e8

Rebased-From: e4b1060
Github-Pull: bitcoin-core#736
Wire the QML resource collection into the bitcoinqml library after the stub window introduces bitcoin_qml.qrc.
Switch bitcoinqml from the bootstrap bitcoin.cpp source to the filtered src/qml source tree after the first backend model sources are present.
Add the filtered test directory under the QML CMake target and remap the initial test paths to the new src/qml location.
Compile and package the QML translation resources after the language settings commit introduces the locale sources.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants